Skip to contentMethod: isReadOnly(ELContext, Object, Object)
1: /*
2: * Copyright (c) 1997, 2022 Oracle and/or its affiliates and others.
3: * All rights reserved.
4: * Copyright 2004 The Apache Software Foundation
5: *
6: * Licensed under the Apache License, Version 2.0 (the "License");
7: * you may not use this file except in compliance with the License.
8: * You may obtain a copy of the License at
9: *
10: * http://www.apache.org/licenses/LICENSE-2.0
11: *
12: * Unless required by applicable law or agreed to in writing, software
13: * distributed under the License is distributed on an "AS IS" BASIS,
14: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15: * See the License for the specific language governing permissions and
16: * limitations under the License.
17: */
18:
19: package jakarta.servlet.jsp.el;
20:
21: import jakarta.servlet.jsp.PageContext;
22: import jakarta.servlet.jsp.JspContext;
23:
24: import jakarta.el.ELContext;
25: import jakarta.el.ELResolver;
26: import jakarta.el.ELException;
27:
28: /**
29: * Defines variable resolution behavior for scoped attributes.
30: *
31: * <p>
32: * This resolver handles variable resolutions where <code>base</code> is <code>null</code>. It searches
33: * <code>PageContext.findAttribute()</code> for a matching attribute. If not found in the case of
34: * <code>setValue</code>, it will create a new attribute in the page scope with the given name.
35: * </p>
36: *
37: * @see jakarta.el.ELResolver
38: * @since JSP 2.1
39: */
40: public class ScopedAttributeELResolver extends ELResolver {
41:
42: /**
43: * If the base object is <code>null</code>, searches the page, request, session and application scopes for an
44: * attribute with the given name and returns it if an attribute exists with the current name.
45: *
46: * <p>
47: * The <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code>
48: * by this resolver before returning if a scoped attribute is matched. If this property is not <code>true</code>
49: * after this method is called, the caller should ignore the return value.
50: * </p>
51: *
52: * @param context The context of this evaluation.
53: * @param base Only <code>null</code> is handled by this resolver. Other values will result in an immediate
54: * return.
55: * @param property The name of the scoped attribute to resolve.
56: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>,
57: * then the scoped attribute; otherwise undefined.
58: * @throws NullPointerException if context is <code>null</code>
59: * @throws ELException if an exception was thrown while performing the property or variable resolution. The
60: * thrown exception must be included as the cause property of this exception, if
61: * available.
62: */
63: @Override
64: public Object getValue(ELContext context, Object base, Object property) {
65:
66: if (context == null) {
67: throw new NullPointerException();
68: }
69:
70: if (base == null) {
71: if (property instanceof String) {
72: String attribute = (String) property;
73: PageContext ctxt = (PageContext) context.getContext(JspContext.class);
74: Object value = ctxt.findAttribute(attribute);
75: if (value != null) {
76: context.setPropertyResolved(true);
77: }
78: return value;
79: }
80: }
81: return null;
82: }
83:
84: /**
85: * If the base object is <code>null</code>, returns <code>Object.class</code> to indicate that any type is valid to
86: * set for a scoped attribute.
87: *
88: * <p>
89: * The <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code>
90: * by this resolver before returning if base is <code>null</code>. If this property is not <code>true</code> after
91: * this method is called, the caller should ignore the return value.
92: * </p>
93: *
94: * @param context The context of this evaluation.
95: * @param base Only <code>null</code> is handled by this resolver. Other values will result in an immediate
96: * return.
97: * @param property The name of the scoped attribute to resolve.
98: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>,
99: * then <code>Object.class</code> otherwise undefined.
100: * @throws NullPointerException if context is <code>null</code>
101: * @throws ELException if an exception was thrown while performing the property or variable resolution. The
102: * thrown exception must be included as the cause property of this exception, if
103: * available.
104: */
105: @Override
106: public Class<Object> getType(ELContext context, Object base, Object property) {
107:
108: if (context == null) {
109: throw new NullPointerException();
110: }
111:
112: if (base == null) {
113: context.setPropertyResolved(true);
114: return Object.class;
115: }
116: return null;
117: }
118:
119: /**
120: * If the base object is <code>null</code>, sets an existing scoped attribute to the new value, or creates a new
121: * scoped attribute if one does not exist by this name.
122: *
123: * <p>
124: * If the provided attribute name matches the key of an attribute in page scope, request scope, session scope, or
125: * application scope, the corresponding attribute value will be replaced by the provided value. Otherwise, a new
126: * page scope attribute will be created with the given name and value.
127: * </p>
128: *
129: * <p>
130: * The <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code>
131: * by this resolver before returning if base is <code>null</code>. If this property is not <code>true</code> after
132: * this method is called, the caller should ignore the return value.
133: * </p>
134: *
135: * @param context The context of this evaluation.
136: * @param base Only <code>null</code> is handled by this resolver. Other values will result in an immediate
137: * return.
138: * @param property The name of the scoped attribute to set.
139: * @param val The value for the scoped attribute.
140: * @throws NullPointerException if context is <code>null</code>.
141: * @throws ELException if an exception was thrown while performing the property or variable resolution. The
142: * thrown exception must be included as the cause property of this exception, if
143: * available.
144: */
145: @Override
146: public void setValue(ELContext context, Object base, Object property, Object val) {
147: if (context == null) {
148: throw new NullPointerException();
149: }
150:
151: if (base == null) {
152: context.setPropertyResolved(true);
153: if (property instanceof String) {
154: PageContext ctxt = (PageContext) context.getContext(JspContext.class);
155: String attr = (String) property;
156: if (ctxt.getAttribute(attr, PageContext.REQUEST_SCOPE) != null)
157: ctxt.setAttribute(attr, val, PageContext.REQUEST_SCOPE);
158: else if (ctxt.getAttribute(attr, PageContext.SESSION_SCOPE) != null)
159: ctxt.setAttribute(attr, val, PageContext.SESSION_SCOPE);
160: else if (ctxt.getAttribute(attr, PageContext.APPLICATION_SCOPE) != null)
161: ctxt.setAttribute(attr, val, PageContext.APPLICATION_SCOPE);
162: else {
163: ctxt.setAttribute(attr, val, PageContext.PAGE_SCOPE);
164: }
165: }
166: }
167: }
168:
169: /**
170: * If the base object is <code>null</code>, returns <code>false</code> to indicate that scoped attributes are never
171: * read-only.
172: *
173: * <p>
174: * The <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code>
175: * by this resolver before returning if base is <code>null</code>. If this property is not <code>true</code> after
176: * this method is called, the caller should ignore the return value.
177: * </p>
178: *
179: * @param context The context of this evaluation.
180: * @param base Only <code>null</code> is handled by this resolver. Other values will result in an immediate
181: * return.
182: * @param property The name of the scoped attribute.
183: * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>,
184: * then <code>false</code> otherwise undefined.
185: * @throws NullPointerException if context is <code>null</code>.
186: * @throws ELException if an exception was thrown while performing the property or variable resolution. The
187: * thrown exception must be included as the cause property of this exception, if
188: * available.
189: */
190: @Override
191: public boolean isReadOnly(ELContext context, Object base, Object property) {
192:• if (context == null) {
193: throw new NullPointerException();
194: }
195:
196:• if (base == null) {
197: context.setPropertyResolved(true);
198: }
199: return false;
200: }
201:
202: /**
203: * If the base object is <code>null</code>, returns <code>String.class</code>. Otherwise, returns <code>null</code>.
204: *
205: * @param context The context of this evaluation.
206: * @param base Only <code>null</code> is handled by this resolver. Other values will result in a
207: * <code>null</code> return value.
208: * @return <code>null</code> if base is not <code>null</code> otherwise <code>String.class</code>.
209: */
210: @Override
211: public Class<String> getCommonPropertyType(ELContext context, Object base) {
212: if (base == null) {
213: return String.class;
214: }
215: return null;
216: }
217:
218: }